home *** CD-ROM | disk | FTP | other *** search
/ Internet Info 1994 March / Internet Info CD-ROM (Walnut Creek) (March 1994).iso / networking / terms / tipx / libacu / hayes.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-10-11  |  6.3 KB  |  303 lines

  1. /*
  2.  * Copyright (c) 1983 The Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms are permitted
  6.  * provided that the above copyright notice and this paragraph are
  7.  * duplicated in all such forms and that any documentation,
  8.  * advertising materials, and other materials related to such
  9.  * distribution and use acknowledge that the software was developed
  10.  * by the University of California, Berkeley.  The name of the
  11.  * University may not be used to endorse or promote products derived
  12.  * from this software without specific prior written permission.
  13.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  14.  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  15.  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  16.  */
  17.  
  18. #ifndef lint
  19. static char sccsid[] = "@(#)hayes.c    5.2 (Berkeley) 9/13/88";
  20. #endif /* not lint */
  21.  
  22. /*
  23.  * Routines for calling up on a Hayes Modem
  24.  * (based on the old VenTel driver).
  25.  * The modem is expected to be strapped for "echo".
  26.  * Also, the switches enabling the DTR and CD lines
  27.  * must be set correctly.
  28.  * NOTICE:
  29.  * The easy way to hang up a modem is always simply to
  30.  * clear the DTR signal. However, if the +++ sequence
  31.  * (which switches the modem back to local mode) is sent
  32.  * before modem is hung up, removal of the DTR signal
  33.  * has no effect (except that it prevents the modem from
  34.  * recognizing commands).
  35.  * (by Helge Skrivervik, Calma Company, Sunnyvale, CA. 1984) 
  36.  */
  37. /*
  38.  * TODO:
  39.  * It is probably not a good idea to switch the modem
  40.  * state between 'verbose' and terse (status messages).
  41.  * This should be kicked out and we should use verbose 
  42.  * mode only. This would make it consistent with normal
  43.  * interactive use thru the command 'tip dialer'.
  44.  */
  45. #include "tip.h"
  46.  
  47. #define    min(a,b)    ((a < b) ? a : b)
  48.  
  49. static    int sigALRM();
  50. static    int timeout = 0;
  51. static    jmp_buf timeoutbuf;
  52. static     char gobble();
  53. #define DUMBUFLEN    40
  54. static char dumbuf[DUMBUFLEN];
  55.  
  56. #define    DIALING        1
  57. #define IDLE        2
  58. #define CONNECTED    3
  59. #define    FAILED        4
  60. static    int state = IDLE;
  61.  
  62. hay_dialer(num, acu)
  63.     register char *num;
  64.     char *acu;
  65. {
  66.     register char *cp;
  67.     register int connected = 0;
  68.     char dummy;
  69. #ifdef ACULOG
  70.     char line[80];
  71. #endif
  72.     if (hay_sync() == 0)        /* make sure we can talk to the modem */
  73.         return(0);
  74.     if (boolean(value(VERBOSE)))
  75.         printf("\ndialing...");
  76.     fflush(stdout);
  77.     ioctl(FD, TIOCHPCL, 0);
  78.     ioctl(FD, TIOCFLUSH, 0);    /* get rid of garbage */
  79.     write(FD, "ATV0E0\r", 7);    /* tell modem to use short status codes */
  80.     if (gobble("A\r") == 'A') {
  81.         gobble("\r");    /* echo is on, need 2 swallows */
  82.         gobble("\r");
  83.     }
  84.     write(FD, "ATDT", 4);    /* send dial command */
  85.     write(FD, num, strlen(num));
  86.     state = DIALING;
  87.     write(FD, "\r", 1);
  88.     connected = 0;
  89.     if ((dummy = gobble("012345678")) != '1')
  90.         error_rep(dummy);
  91.     else
  92.         connected = 1;
  93.     if (connected)
  94.         state = CONNECTED;
  95.     else {
  96.         state = FAILED;
  97.         return (connected);    /* lets get out of here.. */
  98.     }
  99.     ioctl(FD, TIOCFLUSH, 0);
  100. #ifdef ACULOG
  101.     if (timeout) {
  102.         sprintf(line, "%d second dial timeout",
  103.             number(value(DIALTIMEOUT)));
  104.         logent(value(HOST), num, "hayes", line);
  105.     }
  106. #endif
  107.     if (timeout)
  108.         hay_disconnect();    /* insurance */
  109.     return (connected);
  110. }
  111.  
  112.  
  113. hay_disconnect()
  114. {
  115.     char c;
  116.     int len, rlen;
  117.  
  118.     /* first hang up the modem*/
  119. #ifdef DEBUG
  120.     printf("\rdisconnecting modem....\n\r");
  121. #endif
  122.     ioctl(FD, TIOCCDTR, 0);
  123.     sleep(1);
  124.     ioctl(FD, TIOCSDTR, 0);
  125.     goodbye();
  126. }
  127.  
  128. hay_abort()
  129. {
  130.  
  131.     char c;
  132.  
  133.     write(FD, "\r", 1);    /* send anything to abort the call */
  134.     hay_disconnect();
  135. }
  136.  
  137. static int
  138. sigALRM()
  139. {
  140.  
  141.     printf("\07timeout waiting for reply\n\r");
  142.     timeout = 1;
  143.     longjmp(timeoutbuf, 1);
  144. }
  145.  
  146. static char
  147. gobble(match)
  148.     register char *match;
  149. {
  150.     char c;
  151.     int (*f)();
  152.     int i, status = 0;
  153.  
  154.     signal(SIGALRM, sigALRM);
  155.     timeout = 0;
  156. #ifdef DEBUG
  157.     printf("\ngobble: waiting for %s\n", match);
  158. #endif
  159.     do {
  160.         if (setjmp(timeoutbuf)) {
  161.             signal(SIGALRM, f);
  162.             return (0);
  163.         }
  164.         alarm(number(value(DIALTIMEOUT)));
  165.         read(FD, &c, 1);
  166.         alarm(0);
  167.         c &= 0177;
  168. #ifdef DEBUG
  169.         printf((c>' ' && c<0177)?"%c ":"0x%x ", c);
  170. #endif
  171.         for (i = 0; i < strlen(match); i++)
  172.             if (c == match[i])
  173.                 status = c;
  174.     } while (status == 0);
  175.     signal(SIGALRM, SIG_DFL);
  176. #ifdef DEBUG
  177.     printf("\n");
  178. #endif
  179.     return (status);
  180. }
  181.  
  182. error_rep(c)
  183.     register char c;
  184. {
  185.     printf("\n\r");
  186.     switch (c) {
  187.  
  188.     case '0':
  189.         printf("OK");
  190.         break;
  191.  
  192.     case '1':
  193.         printf("CONNECT");
  194.         break;
  195.     
  196.     case '2':
  197.         printf("RING");
  198.         break;
  199.     
  200.     case '3':
  201.         printf("NO CARRIER");
  202.         break;
  203.     
  204.     case '4':
  205.         printf("ERROR in input");
  206.         break;
  207.     
  208.     case '5':
  209.         printf("CONNECT 1200");
  210.         break;
  211.     
  212.     case '6':
  213.         printf("NO DIALTONE");
  214.         break;
  215.  
  216.     case '7':
  217.         printf("BUSY");
  218.         break;
  219.  
  220.     case '8':
  221.         printf("NO ANSWER");
  222.         break;
  223.  
  224.     default:
  225.         printf("Unknown Modem error: %c (0x%x)", c, c);
  226.     }
  227.     printf("\n\r");
  228.     return;
  229. }
  230.  
  231. /*
  232.  * set modem back to normal verbose status codes.
  233.  */
  234. goodbye()
  235. {
  236.     int len, rlen;
  237.     char c;
  238.  
  239.     ioctl(FD, TIOCFLUSH, &len);    /* get rid of trash */
  240.     if (hay_sync()) {
  241.         sleep(1);
  242. #ifndef DEBUG
  243.         ioctl(FD, TIOCFLUSH, 0);
  244. #endif
  245.         write(FD, "ATH0V0\r", 7);        /* insurance */
  246. #ifndef DEBUG
  247.         number(value(DIALTIMEOUT)) = 10;    /* shorten timeout */
  248.         c = gobble("03");
  249.         if (c != '0' && c != '3') {
  250.             printf("cannot hang up modem\n\r");
  251.             printf("please use 'tip dialer' to make sure the line is hung up\n\r");
  252.         }
  253. #endif
  254.         sleep(1);
  255.         ioctl(FD, FIONREAD, &len);
  256. #ifdef DEBUG
  257.         printf("goodbye1: len=%d -- ", len);
  258.         rlen = read(FD, dumbuf, min(len, DUMBUFLEN));
  259.         dumbuf[rlen] = '\0';
  260.         printf("read (%d): %s\r\n", rlen, dumbuf);
  261. #endif
  262.         write(FD, "ATV1E1\r", 7);
  263.         sleep(1);
  264. #ifdef DEBUG
  265.         ioctl(FD, FIONREAD, &len);
  266.         printf("goodbye2: len=%d -- ", len);
  267.         rlen = read(FD, dumbuf, min(len, DUMBUFLEN));
  268.         dumbuf[rlen] = '\0';
  269.         printf("read (%d): %s\r\n", rlen, dumbuf);
  270. #endif
  271.     }
  272.     ioctl(FD, TIOCFLUSH, 0);    /* clear the input buffer */
  273.     ioctl(FD, TIOCCDTR, 0);        /* clear DTR (insurance) */
  274.     close(FD);
  275. }
  276.  
  277. #define MAXRETRY    5
  278.  
  279. hay_sync()
  280. {
  281.     int len, retry = 0;
  282.  
  283.     while (retry++ <= MAXRETRY) {
  284.         write(FD, "\rAT\r", 4);
  285.         sleep(1);
  286.         ioctl(FD, FIONREAD, &len);
  287.         if (len) {
  288.             len = read(FD, dumbuf, min(len, DUMBUFLEN));
  289.             if (index(dumbuf, '0') || 
  290.                (index(dumbuf, 'O') && index(dumbuf, 'K')))
  291.                 return(1);
  292. #ifdef DEBUG
  293.             dumbuf[len] = '\0';
  294.             printf("hay_sync: (\"%s\") %d\n\r", dumbuf, retry);
  295. #endif
  296.         }
  297.         ioctl(FD, TIOCCDTR, 0);
  298.         ioctl(FD, TIOCSDTR, 0);
  299.     }
  300.     printf("Cannot synchronize with hayes...\n\r");
  301.     return(0);
  302. }
  303.